﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include <QObject>
#include "GcsService.h"
#include "IComponent.h"
#include "IDocument.h"
#include "IFamilyLoadOptions.h"


template<typename T> class QList;

namespace gcmp
{
    class IFamily;
}

namespace gmepgcs
{
    struct IProjectComponent;
}

namespace gmepgcs
{
    class GCS_SERVICE_EXPORTS ProjectLoadedComponentService : public QObject
    {
        Q_OBJECT

    private:
        explicit ProjectLoadedComponentService();
        ProjectLoadedComponentService(ProjectLoadedComponentService &) = default;
        ProjectLoadedComponentService &operator=(ProjectLoadedComponentService &) = default;
        virtual ~ProjectLoadedComponentService();
    
    public:
        static ProjectLoadedComponentService *Get();

    public:
        bool PlaceComponent(std::wstring componentName, std::wstring &message);
        bool PlaceComponentInculdeFamilyType(const std::wstring &uniqueComponentName, const std::wstring &componentName, std::wstring familyTypeName, const std::wstring &componentCategoryStandardCode, std::wstring &message);
        //void PlaceComponent(std::wstring componentName, std::wstring specification, std::wstring &message);
        //void PlaceComponentFromFile(std::wstring componentFilePath, std::wstring componentCloudId, std::wstring componentCloudVersion);

        // 根据familyId 查找此文档是否已经载入
        bool IsComponentLoadedByCloudId(const gcmp::IDocument *pDoc, const std::wstring& componentCloudId);
        // 根据 familyName 查找此文档是否已经有同名族
        bool CheckComponentExistByName(const gcmp::IDocument *pDoc, const std::wstring& componentName);

        /// \brief 根据ID和名称查找文档中是否已存在对应的族
        ///
        /// \param pDoc 待搜索的文档指针
        /// \param familyId 要查找的族ID，将与gcmp::IFamilyConfigElement中所记录的FamilyIdInCloud进行对比
        /// \param familyName 要查找的族名称
        bool CheckFamilyExistByIdAndName(const gcmp::IDocument *pDoc, const std::wstring &familyId, const std::wstring& familyName);

        std::shared_ptr<IProjectComponent> FindLoadedComponentByCloudId(std::wstring componentCloudId);

        bool IsComponentUpdatable(std::wstring componentCloudId, int32_t componentCloudVersion);

        // 获取名称
        std::wstring GetUniqueFamilyName(const gcmp::IDocument *pDoc, const std::wstring &potentialFamilyName) const;

        bool LoadComponentIntoProject(
            gcmp::IDocument *pCurrentDoc,
            const std::wstring &oldComponentName,
            const std::wstring &componentName,
            const std::wstring &componentCategoryStandardCode,
            bool bLoadFromPublicLibrary = false) const;

        bool RenameFamily(const std::wstring &familyOldName, const std::wstring &familyNewName);

        //std::map<std::wstring, int32_t> GetLoadedComponentIdVersions();

    //signals:
    //    void FinishIsComponentLoadedByCloudId(bool result);

    private:
        bool StartCreateFamilyInstance(std::wstring familyName, std::wstring familyType, std::wstring &message);
        bool StartCreateFamilyInstance(const std::wstring &uniquefamilyName, const std::wstring &familyName, const std::wstring &familyType, const std::wstring &componentCategoryStandardCode, std::wstring &message);
        //bool PrivateLoadComponentIntoProject(std::wstring componentFilePath, std::wstring componentCloudId, std::wstring componentCloudVersion, std::wstring &loadedFamilyName);
       // bool PrivateUpdateComponentIntoProject(std::wstring componentFilePath, std::wstring componentCloudId, std::wstring componentCloudVersion, std::wstring &loadedFamilyName, gcmp::IFamilyLoadOptions *option);
        
    private:
        static ProjectLoadedComponentService *s_pInstance;
    };
}

